----------------------------------------------------------------------------
--agregar al WHERE artm.precio > 0.00 para evitar division por cero
---------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION public.tg_artm_preultcompra()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF
AS $BODY$
DECLARE
vOldId ArtM.Id%TYPE;
vOldModifica Com.ModificaPrecios%TYPE;
vOldVerPreciosConIva Com.VerPreciosConIva%TYPE;
vOldFecha ComM.Fecha%TYPE;
vOldIdArt ArtM.IdArt%TYPE;
vOldPreId    Pre.Id%TYPE;
vOldPreIdMon Pre.Id%TYPE;
cMovIguales REFCURSOR;
vMId          ArtM.Id%TYPE;
vMIdComM      ArtM.IdComM%TYPE;
vMPrecio      ArtM.Precio%TYPE;
vMPrecioMon   ArtM.Precio%TYPE;
vMTipoCom  ComM.TipoCom%TYPE;
vMFecha    ComM.Fecha%TYPE;
vMModifica Com.ModificaPrecios%TYPE;
vValorReal    ArtM.Precio%TYPE;
vValorRealMon ArtM.Precio%TYPE;
vValor        PreXArt.Valor%TYPE;

BEGIN
-- Se recupera informacion extra del movimiento
SELECT OLD.Id, Com.ModificaPrecios, Com.verpreciosconiva, ComM.Fecha, OLD.IdArt, 
       --case when Old.CodValMon = '$' then Com.CodPre else Com.CodPreMon end, 
       Pre.Id, PreMon.Id   -- Cod.ComPre varia segun la moneda elegida, cod.compremon siempre es la exranjera
INTO vOldId, vOldModifica, vOldVerPreciosConIva, vOldFecha, vOldIdArt, vOldPreId, vOldPreIdMon
FROM ComM
INNER JOIN Com ON (ComM.TipoCom = Com.Tipo)
INNER JOIN Pre ON (CASE WHEN OLD.CODVALMON = '$' THEN Com.CodPre ELSE COM.CODPREMON END = Pre.Cod AND 1 = Pre.IdPreLis)  -- Segunda condicion en el join con Pre es porque falta un campo IdPreLis en COM  (Com.IdPreLis = Pre.IdPreLis) 
LEFT  JOIN Pre PreMon ON (CASE WHEN OLD.CODVALMON = '$' THEN Com.CodPreMon ELSE COM.CODPRE END = PreMon.Cod AND 1 = PreMon.IdPreLis)  -- Segunda condicion en el join con Pre es porque falta un campo IdPreLis en COM  (Com.IdPreLis = Pre.IdPreLis) 
WHERE (ComM.Id = OLD.IdComM);

-- Old.CodPreMon    Moneda del movimiento...
-- vOldModifica y com.modificaprecios vale S y >, pero ademas: A si modifica Ambas Monedas, M si modifica ambas monedas si es mayor (cada una por separado)
--IF vOldModifica IS NOT NULL AND vOldModifica in ('S', '>','A','M') THEN
IF COALESCE(vOldModifica, '') IN ('S','>','A','M') THEN
   OPEN cMovIguales FOR -- Este cursor selecciona todos los movimientos que afectaron el mismo precio que el movimiento actual
       SELECT ArtM.Id, ArtM.IdComM, -- ArtM.Precio, 
              CASE WHEN vOldVerPreciosConIva = 'S' THEN 
                CASE WHEN artm.CODVALMON = '$' THEN artm.PrecioCIva 
                     ELSE artm.PRECIOMONEDA END 
              ELSE
                CASE WHEN artm.CODVALMON = '$' THEN artm.Precio
                     ELSE artm.PRECIOMONEDA END 
              END,
              ComM.TipoCom, ComM.Fecha, Com.ModificaPrecios,
              CASE WHEN vOldVerPreciosConIva = 'S' THEN artm.PRECIOMONEDA * ARTM.PRECIOCIVA / ARTM.PRECIO
                   ELSE CASE WHEN old.codvalmon = '$' THEN artm.PrecioMoneda 
                             ELSE artm.Precio END 
              END --  PrecioMon
        FROM ArtM
        INNER JOIN ComM ON (ArtM.IdComM = ComM.Id)
        INNER JOIN Com  ON (ComM.TipoCom = Com.Tipo)
        INNER JOIN Pre  ON (CASE WHEN ArtM.CODVALMON = '$' THEN Com.CodPre ELSE COM.CODPREMON END = Pre.Cod) AND (1 = Pre.IdPreLis) -- Segunda condicion es porque falta un campo IdPreLis en COM  (Com.IdPreLis = Pre.IdPreLis) 
        WHERE (ArtM.IdArt = OLD.IdArt) AND 
              (Com.ModificaPrecios IN ('S','>','A','M')) AND (Pre.Id = vOldPreId) AND
              (artm.preciolista is null or Artm.PrecioLista <> -1) AND
			  ( artm.precio > 0.00)
        ORDER BY ComM.Fecha DESC, ArtM.Id DESC;
         
-- El fetch que sigue tomara el ultimo movimiento (x fecha desc) de ese articulo para las condiciones dadas, 
-- que puede o no ser el que se esta cargando ahora.
        FETCH cMovIguales INTO vMId, vMIdComM, vMPrecio, vMTipoCom, vMFecha, vMModifica, vMPrecioMon;
        vValorReal    := vMPrecio;
        vValorRealMon := vMPrecioMon;

        WHILE (vMModifica = '>') LOOP
           FETCH cMovIguales INTO vMId, vMIdComM, vMPrecio, vMTipoCom, vMFecha, vMModifica, vMPrecioMon;
           EXIT WHEN (NOT FOUND);
           IF (vMPrecio > vValorReal) THEN
              vValorReal := vMPrecio;
           END IF;
           IF (vMPrecioMon > vValorRealMon) THEN
              vValorRealMon := vMPrecioMon;
           END IF;
        END LOOP;
   CLOSE cMovIguales;

   IF (vValorReal IS NOT NULL) THEN -- Solo modifica el precio si encuentra algun movimiento que lo modifica
      IF vOldModifica IN ('>', 'M') THEN
         SELECT COALESCE(Valor, 0.00) INTO vValor FROM prexart WHERE idart = vOldIdart AND IdPre = vOldPreId;
         IF vValorReal > vValor THEN
            UPDATE PreXArt SET Valor = vValorReal WHERE (IdPre = vOldPreId) AND (IdArt = vOldIdArt);
            IF NOT FOUND THEN
               INSERT INTO PREXART (IdArt, IdPre, Valor) values (IdPre,IdArtv,vValorReal);
            END IF;
         END IF;
      ELSE
         IF vOldModifica IN ('S', 'A') AND (OLD.idcomm = vMIdComm) THEN
            UPDATE PreXArt SET Valor = vValorReal WHERE (IdPre = vOldPreId) AND (IdArt = vOldIdArt);
         END IF;   
      END IF;
      
-- Si modificaba ambas monedas, ahora va la moneda extranjera (que puede ser la misma u otra)
      IF vOldModifica = 'M' then
         SELECT COALESCE(Valor, 0.00) INTO vValor FROM prexart WHERE idart = vOldIdart AND IdPre = vOldPreIdMon;
         IF vValorRealMon > vValor THEN 
            UPDATE PreXArt SET Valor = vValorRealMon WHERE (IdPre = vOldPreIdMon) AND (IdArt = vOldIdArt);
         END IF;
      ELSE
         IF (vOldModifica = 'A')  AND (OLD.idcomm = vMIdComm) THEN
            UPDATE PreXArt SET Valor = vValorRealMon WHERE (IdPre = vOldPreIdMon) AND (IdArt = vOldIdArt);
         END IF;   
      END IF;
/*  Antes lo borraba. Ahora no porque elimina precios que habian sido cargados a mano.
    ELSE
      DELETE FROM PreXArt WHERE (IdPre = vOldPreId)    AND (IdArt = vOldIdArt);
      DELETE FROM PreXArt WHERE (IdPre = vOldPreIdMon) AND (IdArt = vOldIdArt);
*/
   END IF;
END IF;
RETURN NEW;
END;
$BODY$;

ALTER FUNCTION public.tg_artm_preultcompra() OWNER TO abacouser;

--    -----------------------------------------------
SELECT aaversion('509.02','509.01');
--    ----------------------------------------------
